//==================================================================
/// transformer.h
///
/// Created by Davide Pasca - 2009/10/5
/// See the file "license.txt" that comes with this project for
/// copyright info. 
//==================================================================

#ifndef TRANSFORMER_H
#define TRANSFORMER_H

//==================================================================
//==================================================================
class transformer
{
public:
	float   _screen_d;
	float   _foff_y;
	float	_hf_wd, _hf_he;
	float	_zz;
	int		_clip_flags;

public:
	//==================================================================
	transformer( U32 w, U32 h, float screen_d )
	{
		Resize( w, h, screen_d );
	}

	//==================================================================
	void Resize( U32 w, U32 h, float screen_d )
	{
		_screen_d = screen_d;

		_hf_wd = w * 0.5f;
		_hf_he = h * 0.5f;
	}

	//==================================================================
	void SetScreenHe( U32 he )
	{
		_hf_he = he * 0.5f;
	}

	//==================================================================
	void offy_set( float foy )
	{
		_foff_y = foy;
	}

	//==================================================================
	// posCS: position in camera-space
	bool Project( const Vec3 &posCS, Vec3 &out_posSS ) const
	{
		out_posSS.x	= _hf_wd;
		out_posSS.y	= _hf_he;
		out_posSS.z	= 0;

		if ( posCS.z > 0 )
		{
			float sz = _screen_d / posCS.z;	
			out_posSS.x	+= posCS.x * sz;
			out_posSS.y	-= (_foff_y + posCS.y) * sz;
			out_posSS.z	= sz; 

			return true;
		}

		return false;
	}

	//==================================================================
	void zz_setf( float zz )
	{
		_zz = zz;
	}

	//==================================================================
	float xform_zf( float z )
	{
		if ( z <= 0 )
		{
			_zz = 0.01f;
			_clip_flags = 1;
		}
		else
		{
			_zz = (float)_screen_d / z;
			_clip_flags = 0;
		}
			
		return _zz;
	}

	//==================================================================
	int xform_xf( float x )
	{
		return (int)(_hf_wd + x * _zz);
	}

	//==================================================================
	int xform_yf( float y )
	{
		y += _foff_y;
		return (int)(_hf_he - y * _zz);
	}
};

#endif
